package com.hopechart.micro.common.generator;

import com.google.common.base.CaseFormat;
import com.hopechart.micro.util.StringUtil;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author daijiang@hopechart.com
 */
public abstract class AbstractGenerator {

	protected Configuration configuration = null;

	protected static final String AUTHOR = "daijiang@hopechart.com";

	protected static final String DATE = new SimpleDateFormat("yyyy/MM/dd").format(new Date());

	/**
	 * 项目在硬盘上的基础路径
	 */
	protected static final String PROJECT_PATH = System.getProperty("user.dir");

	/**
	 * java文件路径
	 */
	protected static final String JAVA_PATH = "/src/main/java";

	/**
	 * 资源文件路径
	 */
	protected static final String RESOURCES_PATH = "/src/main/resources";

	/**
	 * 项目基础包
	 */
	protected static final String BASE_PACKAGE = "com.hopechart.micro";

	/**
	 * 项目 Controller 所在包
	 */
	protected static final String CONTROLLER_PACKAGE = "com.hopechart.micro.web.controller";

	/**
	 * 包转成路径 com.platform ---> com/platform
	 * 
	 * @param packageName
	 * @return
	 */
	private static String packageConvertPath(String packageName) {
		return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
	}

	/**
	 * 获取Module包
	 * 
	 * @return
	 */
	private static String getModule() {
		return BASE_PACKAGE + ".domain";
	}

	public static String getMapperPackage() {
		return getModule() + ".mapper.master";
	}

	/**
	 * 获取POJO包
	 * 
	 * @return
	 */
	public static String getPojoPackage() {
		return getModule() + ".entities.master";
	}

	/**
	 * 获取Service包
	 * 
	 * @return
	 */
	public static String getServicePackage() {
		return getModule() + ".service";
	}

	/**
	 * 获取Service实现包
	 * 
	 * @return
	 */
	public static String getServiceImplPackage() {
		return getServicePackage() + ".impl";
	}

	/**
	 * 获取POJO存放路径
	 * 
	 * @return
	 */
	public static String getPojoSavePath() {
		String path = PROJECT_PATH + JAVA_PATH + packageConvertPath(getPojoPackage());
		return path.replace("\\", "/");
	}

	/**
	 * 获取Mapper存放路径
     *
	 * @return
	 */
	public static String getMapperSavePath() {
		String path = PROJECT_PATH + JAVA_PATH + packageConvertPath(getMapperPackage());
		return path.replace("\\", "/");
	}

	/**
	 * 获取Mapper xml存放路径
	 * 
	 * @param modelName
	 * @return
	 */
	public static String getMapperXmlSavePath(String modelName) {
		String path = PROJECT_PATH + RESOURCES_PATH + "/mapper/" + modelName;
		return path.replace("\\", "/");
	}

	/**
	 * 获取Service存放路径
	 * 
	 * @return
	 */
	public static String getServiceSavePath() {
		String path = PROJECT_PATH + JAVA_PATH + packageConvertPath(getServicePackage());
		return path.replace("\\", "/");
	}

	/**
	 * 获取Service 实现存放路径
	 * 
	 * @return
	 */
	public static String getServiceImplSavePath() {
		String path = PROJECT_PATH + JAVA_PATH + packageConvertPath(getServiceImplPackage());
		return path.replace("\\", "/");
	}

	/**
	 * 获取Controller存放路径
	 * 
	 * @return
	 */
	public static String getControllerSavePath() {
		String path = PROJECT_PATH + JAVA_PATH + packageConvertPath(CONTROLLER_PACKAGE);
		return path.replace("\\", "/");
	}

	public Configuration getFreemarkerConfiguration() {
		if (configuration == null) {
			configuration = initFreemarkerConfiguration();
			return configuration;
		}
		return configuration;
	}

	private Configuration initFreemarkerConfiguration() {
		Configuration cfg;
		try {
			String filePath = getClass().getResource("").getPath();
			File templateFile = new File(filePath);
			cfg = new Configuration(Configuration.VERSION_2_3_23);
			cfg.setDirectoryForTemplateLoading(templateFile);
			cfg.setDefaultEncoding("UTF-8");
			cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
		} catch (IOException e) {
			throw new RuntimeException("模板初始化异常", e);
		}
		return cfg;
	}

	/**
	 * 下划线转成驼峰, 首字符为大写 PM_T_DEMO ==> PmTDemo
	 *
	 * @param tableName
	 *            表名, PM_T_DEMO
	 * @return
	 */
	protected String tableNameConvertUpperCamel(String tableName) {
		return StringUtil.upperUnderscoreToUpperCamel(splitTableName(tableName));
	}

	/**
	 * 截取表前缀
	 * 
	 * @param tableName
	 * @return
	 */
	private String splitTableName(String tableName) {
		return tableName.substring(tableName.indexOf("_") + 1);
	}

	/**
	 * 预置页面所需数据
	 *
	 * @param tableName
	 *            表名
	 * @return
	 */
	protected Map<String, Object> getTemplateParam(String tableName, String modelName) {
		Map<String, Object> data = new HashMap<>();
		if(StringUtil.isEmpty(modelName)) {
			// USER_NAME to UserName
			modelName = tableNameConvertUpperCamel(tableName);
		}

		data.put("date", DATE);
		data.put("author", AUTHOR);
		data.put("basePackage", BASE_PACKAGE);
		// 全部小写
		data.put("module", modelName.toLowerCase());
		// 首字母大写
		data.put("modelNameUpperCamel", modelName);
		// 首字母小写
		data.put("modelNameLowerCamel", StringUtil.upperCamelToLowerCamel(modelName));
		// 首字母小写
		data.put("baseRequestMapping", StringUtil.upperCamelToLowerCamel(modelName));

		return data;
	}

	/**
	 * 下划线转成驼峰, 首字符为小写 gen_test_demo ==> genTestDemo
	 *
	 * @param tableName
	 *            表名
	 * @return
	 */
	protected String tableNameConvertLowerCamel(String tableName) {
		return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, splitTableName(tableName).toLowerCase());
	}

	public void executor(String tableName, String modelName) {

	}

	public List<String> execute(String dbUser, String dbUserPass, String url, String driverClass, String tableName) {
		return null;
	}
}
